package com.example.huajia.wx.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.example.huajia.wx.common.util.R;
import com.example.huajia.wx.config.shiro.JwtUtil;
import com.example.huajia.wx.controller.form.*;
import com.example.huajia.wx.exception.HJException;
import com.example.huajia.wx.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.example.huajia.wx.common.util.RedisKey.USER_INFO_KEY;

@RestController
@RequestMapping("/user")
@Api("用户模块web接口")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private RedisTemplate redisTemplate;
    @Value("${emos.jwt.cache-expire}")
    private int cacheExpire;

    @PostMapping("/register")
    @ApiOperation("注册接口")
    public R register(@Valid @RequestBody RegisterForm form) {
        int id = userService.registerUser(form.getCode(), form.getNickName(), form.getPhoto());
        String token = jwtUtil.createToken(id);
        saveCacheToken(token, id);
        return R.ok("用户注册成功").put("token", token);
    }

    @PostMapping("/login")
    @ApiOperation("登录接口")
    public R login(@Valid @RequestBody LoginForm form, @RequestHeader("token") String token) {
        Integer id;
        if (StrUtil.isNotEmpty(token)) {
            try {
                jwtUtil.verifierToken(token);   //验证令牌的有效性
            } catch (TokenExpiredException e) {
                //如果令牌过期就生成新的令牌
                id = userService.login(form.getCode());
                token = jwtUtil.createToken(id);
                saveCacheToken(token, id);
            }
            id = jwtUtil.getUserId(token);
        } else {
            id = userService.login(form.getCode());
            token = jwtUtil.createToken(id);
            saveCacheToken(token, id);
        }
        return R.ok("登录成功").put("token", token);
    }

    private void saveCacheToken(String token, int userId) {
        redisTemplate.opsForValue().set(token, userId + "", cacheExpire, TimeUnit.DAYS);
    }

    @GetMapping("/searchUserSummary")
    @ApiOperation("查询用户摘要信息")
    public R searchUserSummary(@RequestHeader("token") String token) {
        int userId = jwtUtil.getUserId(token);
        HashMap map = userService.searchUserSummary(userId);
        return R.ok().put("result", map);
    }

    @PostMapping("/searchMembers")
    @ApiOperation("查询成员")
    public R searchMembers(@Valid @RequestBody SearchMembersForm form) {
        if (!JSONUtil.isJsonArray(form.getMembers())) {
            throw new HJException("members不是JSON数组");
        }
        List param = JSONUtil.parseArray(form.getMembers()).toList(Integer.class);
        ArrayList list = userService.searchMembers(param);
        return R.ok().put("result", list);
    }

    @PostMapping("/selectUserPhotoAndName")
    @ApiOperation("查询用户姓名和头像")
    public R selectUserPhotoAndName(@Valid @RequestBody SelectUserPhotoAndNameForm form) {
        if (!JSONUtil.isJsonArray(form.getIds())) {
            throw new HJException("参数不是JSON数组");
        }
        List<Integer> param = JSONUtil.parseArray(form.getIds()).toList(Integer.class);
        List<HashMap> list = userService.selectUserPhotoAndName(param);
        return R.ok().put("result", list);
    }


    @PostMapping("/searchUserById")
    @ApiOperation("查询用户数据")
    public R searchUserById(@RequestHeader("token") String token) {
        int userId = jwtUtil.getUserId(token);
        //先去redis查询是否存在
        String key = USER_INFO_KEY + userId;
        List range = redisTemplate.opsForList().range(key, 0, 40);
        if (range.isEmpty()) {
            //如果为空，则需调用数据库查询
            ArrayList<HashMap> list = userService.searchUserById(userId);
            return R.ok().put("result", list);
        }
        return R.ok().put("result", range);
    }


    @PostMapping("/updateUserInfo")
    @ApiOperation("更新用户数据")
    public R updateUserInfo(@Valid @RequestBody UpdateUserInfoForm form, @RequestHeader("token") String token) {
        int userId = jwtUtil.getUserId(token);
        HashMap param = new HashMap();
        param.put("name", form.getName());
        param.put("sex", form.getSex());
        param.put("tel", form.getTel());
        param.put("nickname", form.getNickname());
        param.put("photo", form.getPhoto());
        param.put("introduction", form.getIntroduction());
        param.put("birthday", form.getBirthday());
        param.put("address", form.getAddress());
        param.put("email", form.getEmail());
        param.put("userId", userId);
        int rows = userService.updateUserInfo(param);
        return R.ok().put("result", rows);
    }

    @GetMapping("/searchUserContactList")
    @ApiOperation("查询通讯录列表")
    public R searchUserContactList() {
        JSONObject json = userService.searchUserContactList();
        return R.ok().put("result", json);
    }

    @GetMapping("/searchUserPoint")
    @ApiOperation("查询用户积分")
    public R searchUserPoint(@RequestHeader("token") String token) {
        int id = jwtUtil.getUserId(token);
        int point = userService.searchUserPoint(id);
        return R.ok().put("result", point);
    }

}
